import json
import re

from django import http
from django.conf import settings
from django.contrib.auth import login
from django.shortcuts import redirect, render

from django.views import View
from django_redis import get_redis_connection

from users.models import User
from meiduo_mall.utils import sinaweibopy3
from weibo.models import OAuthSinaUser


class WeiboLoginView(View):
    def get(self, request):
        client = sinaweibopy3.APIClient(app_key=settings.APP_KEY, app_secret=settings.APP_SECRET,
                                        redirect_uri=settings.REDIRECT_URL)
        login_url = client.get_authorize_url()
        return redirect(login_url)


class WeiboCallbackView(View):
    def get(self, request):
        return render(request, 'sina_callback.html')


class WeiboOauthUserView(View):
    def get(self, request):
        # 获取参数code
        code = request.GET.get("code")
        client = sinaweibopy3.APIClient(app_key=settings.APP_KEY, app_secret=settings.APP_SECRET,
                                        redirect_uri=settings.REDIRECT_URL)
        result = client.request_access_token(code)
        uid = result.uid
        try:
            sinauser = OAuthSinaUser.objects.get(uid=uid)
        except OAuthSinaUser.DoesNotExist:
            return http.JsonResponse({"user_id": None, "token": result.access_token, "uid": uid})
        user_id = sinauser.user_id
        user_name = User.objects.get(id=user_id).username
        response = http.JsonResponse(
            {"user_id": user_id, "username": user_name, "token": result.access_token, "uid": uid})
        response.set_cookie("username", user_name, max_age=3600 * 24 * 2)
        return response

    def post(self, request):
        # 获取参数
        dict_data = json.loads(request.body.decode())
        mobile = dict_data.get("mobile")
        password = dict_data.get("password")
        sms_code = dict_data.get("sms_code")
        uid = dict_data.get("uid")
        access_token = dict_data.get("access_token")
        # 校验参数
        # 为空校验
        if not all([mobile, password, sms_code, uid]):
            return http.HttpResponseForbidden("参数不全")
        # 校验手机号格式
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden("手机号码格式有误")
        # 校验密码格式
        if not re.match(r'^[0-9a-zA-Z]{8,20}$', password):
            return http.HttpResponseForbidden("密码格式有误")
        # 校验短信验证码正确性
        redis_conn = get_redis_connection("code")
        redis_sms_code = redis_conn.get("sms_code_%s" % mobile)
        if not redis_sms_code:
            return http.HttpResponseForbidden("短信验证码已过期")
        if sms_code != redis_sms_code.decode():
            return http.HttpResponseForbidden("短信验证码填写有误")
        # 判断是否存在美多用户，如果存在直接绑定，不存在则创建一个新用户
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            # 创建美多用户
            user = User.objects.create_user(username=mobile, password=password, mobile=mobile)
            # 绑定美多用户和微博用户
            OAuthSinaUser.objects.create(user=user, uid=uid)
            # 状态保持
            login(request, user)
            request.session.set_expiry(3600 * 24 * 2)
            # 返回user_id等数据
            data = {
                "token": access_token,
                "user_id": user.id,
                "username": user.username
            }
            response = http.JsonResponse(data)
            response.set_cookie("username", user.username, max_age=3600 * 24 * 2)
            return response
        else:
            # 校验密码是否正确
            if not user.check_password(password):
                return http.HttpResponseForbidden("密码错误")
            # 绑定用户
            OAuthSinaUser.objects.create(user=user, uid=uid)
            # 状态保持
            login(request, user)
            request.session.set_expiry(3600 * 24 * 2)
            # 返回user_id等数据
            data = {
                "token": access_token,
                "user_id": user.id,
                "username": user.username
            }
            response = http.JsonResponse(data)
            response.set_cookie("username", user.username, max_age=3600 * 24 * 2)
            return response
